package de.haw.gka.a1;


import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.*;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;

import org.jgrapht.UndirectedGraph;
import org.jgrapht.VertexFactory;
import org.jgrapht.alg.EulerianCircuit;
import org.jgrapht.graph.AbstractGraph;
import org.jgrapht.graph.DefaultDirectedWeightedGraph;
import org.jgrapht.graph.DefaultEdge;
import org.jgrapht.graph.DefaultWeightedEdge;
import org.jgrapht.graph.DirectedPseudograph;
import org.jgrapht.graph.Pseudograph;
import org.jgrapht.graph.WeightedPseudograph;
import org.jgrapht.generate.CompleteGraphGenerator;


public class CreateDia extends JDialog implements SearchTyps{

	/**
	 * ToDo einbinden von Selbstbestimmungen von der Edges
     *
	 */

	private static final long serialVersionUID = 1L;
	private static CreateDia instance;
	private static int dialogTyp;
	private int anzahlKnoten;
	private Main mainFrame;
	
	private CreateDia(int typ, Main frame){
		dialogTyp = typ;
		switch(dialogTyp){
		case random:
			initRandom();
			mainFrame = frame;
			break;
		case userCase:
			
			break;
		}
	}
	
	
	public static CreateDia getInstance(int typ, Main frame){
		if(instance == null || typ != dialogTyp) instance = new CreateDia(typ, frame);
		instance.setVisible(true);
		return instance;
	}
	
	
	private void initRandom(){	
		this.setResizable(false);
		this.setLayout(null);
		checkGewichtet.setBounds(new Rectangle(5,5,100,21));
		checkAttr.setBounds(new Rectangle(110,5, 100,21));
		checkGerichtet.setBounds(new Rectangle(220,5,100,21));
        checkZusammen.setBounds(new Rectangle(330,5,150,21));
		
		lblAnzahlKnoten.setBounds(new Rectangle(5,45,120,21));
		txtAnzahlKnoten.setBounds(new Rectangle(120,45,60,21));

        lblMaxAnzahlKanten.setBounds(new Rectangle(200,45,150,21));
        lblAnzeigeMaxKanten.setBounds(new Rectangle(360,45,75,21));

        lblAnzahlKanten.setBounds(new Rectangle(5,70,120,21));
        txtAnzahlKanten.setBounds(new Rectangle(120,70,60,21));

        checkManualEdges.setBounds(new Rectangle(200,70,180,21));
		
		btnCreate.setBounds(new Rectangle(75,120,150,21));
		btnCancel.setBounds(new Rectangle(235,120,80,21));

        lblAusgabe.setBounds(new Rectangle(50,160,180,21));
		
		this.getContentPane().add(btnCancel,null);
		this.getContentPane().add(btnCreate,null);
		
		this.getContentPane().add(checkGewichtet,null);
		this.getContentPane().add(checkAttr,null);
		this.getContentPane().add(checkGerichtet,null);
        this.getContentPane().add(checkZusammen, null);
		this.getContentPane().add(lblAnzahlKnoten,null);
		this.getContentPane().add(txtAnzahlKnoten,null);
        this.getContentPane().add(checkManualEdges, null);

        this.getContentPane().add(txtAnzahlKanten, null);
        this.getContentPane().add(lblAnzahlKanten, null);
		this.getContentPane().add(lblMaxAnzahlKanten, null);
        this.getContentPane().add(lblAnzeigeMaxKanten, null);
        this.getContentPane().add(lblAusgabe, null);

		this.setSize(525,220);
		
		actions();
	}
	
	private void actions(){
		btnCreate.addActionListener(new ActionListener() {			
			@Override
			public void actionPerformed(ActionEvent e) {
				switchGraph();
				switch(dialogTyp){
				case random:
					randomAction(e);
					break;
				case userCase:
	                //ToDo
	 				break;
				}
			}
		});
		btnCancel.addActionListener(new ActionListener() {		
			@Override
			public void actionPerformed(ActionEvent e) {
				cancelAction(e);	
			}
		});

        checkGerichtet.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                refreshMaxAnzahl();
            }
        });

        checkGewichtet.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if(!checkAttr.isSelected() && checkGewichtet.isSelected()) checkAttr.setSelected(true);
            }
        });

        checkZusammen.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if(checkZusammen.isSelected() && (!checkAttr.isSelected() || !checkGewichtet.isSelected())) {
                    checkAttr.setSelected(true);
                    checkGewichtet.setSelected(true);
                    checkGerichtet.setSelected(false);
                }

            }
        });

        txtAnzahlKnoten.addKeyListener(new KeyListener() {
            @Override
            public void keyTyped(KeyEvent e) {
            }

            @Override
            public void keyPressed(KeyEvent e) {
            }

            @Override
            public void keyReleased(KeyEvent e) {
                refreshMaxAnzahl();
            }
        });

        checkManualEdges.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if(checkManualEdges.isSelected()) txtAnzahlKanten.setEditable(true);
                else txtAnzahlKanten.setEditable(false);
            }
        });
	}

    void refreshMaxAnzahl(){
        try{
            int anzahlKnoten = Integer.valueOf(txtAnzahlKnoten.getText()).intValue();
            int maxAnzahlKanten = MaxAnzahlkanten(anzahlKnoten);
            if(!checkGerichtet.isSelected())maxEdges = maxAnzahlKanten;
            else maxEdges = (2*maxAnzahlKanten);
            lblAnzeigeMaxKanten.setText(""+maxEdges);
        }catch(NumberFormatException e){
            lblAnzeigeMaxKanten.setText("");
        }

    }


    private int MaxAnzahlkanten(int anzahlKnoten) {
        return recMaxAnzahlkanten(anzahlKnoten, 0);

    }

    private int recMaxAnzahlkanten(int i, int accu) {
        if(i > 1) return recMaxAnzahlkanten(i-1, accu + (i-1));
        return accu;
    }


    void randomAction(ActionEvent e){
		AbstractGraph<? , ?> aGraph;
		try{
			anzahlKnoten = Integer.valueOf(txtAnzahlKnoten.getText()).intValue();
			if(anzahlKnoten < 0){
				JOptionPane.showMessageDialog(this, "Hier dürfen nur Elemente der\n" +
						"Natürlichenzahlen eingegeben werden!\n" +
						"Und "+ anzahlKnoten +" gehört nicht dazu", "Fehler...", JOptionPane.ERROR_MESSAGE);
				return;
			}

            out("Self: " + isSelfEgdes);
            if(isSelfEgdes){
                userEdges = Integer.valueOf(txtAnzahlKanten.getText()).intValue();
                if(userEdges < 0 && userEdges > maxEdges)  {
                    JOptionPane.showMessageDialog(this, "Hier dürfen nur Elemente der\n" +
                            "Natürlichenzahlen eingegeben werden & die Anzahl \nder Edges darf nicht größer sein als die\n" +
                            "Maximale Anzahl von Edges!" +
                            "Und "+ userEdges +" gehört nicht dazu", "Fehler...", JOptionPane.ERROR_MESSAGE);
                    return;
                }
            }

			if(isGewichtet){
				aGraph = createGewichtetGraph();
				
			}else{
				aGraph = createUngewichtetGraph();
			}
			
			mainFrame.addGraph(aGraph, anzahlKnoten, "");
            if(isSelfEgdes && isZusammenhängend && userEdges != aGraph.edgeSet().size())
                JOptionPane.showMessageDialog(mainFrame,"Sorry, aber die Abweichungkommt zu stande da es ja ein Euler ergeben soll\n" +
                        "Du wolltes :" + userEdges +" es sind aber nun " + aGraph.edgeSet().size(), "Ups", JOptionPane.INFORMATION_MESSAGE);
		}catch (NumberFormatException ne) {
			JOptionPane.showMessageDialog(this, "Hier dürfen nur Elemente der\n" +
					"Natürlichenzahlen eingegeben werden!\n" +
					"Und "+ txtAnzahlKnoten.getText() +" ODER " + maxEdges +" \ngehört nicht dazu", "Fehler...", JOptionPane.ERROR_MESSAGE);
		}
		
	}

	///////////////////////////////////////////////////
	// Oberste ebene
	/////////////////
	
	private AbstractGraph<?, DefaultWeightedEdge> createGewichtetGraph(){
		if(isAttr){
			return createGewichtetAttrGraph();
		}else{
			return createGewichtetUnAttrGraph();
		}		
	}
	
	private AbstractGraph<?, DefaultEdge> createUngewichtetGraph(){
		if(isAttr){
			return createAttrUnGewichtetGraph();
		}else{
			return createUnAttrUnGewichtetGraph();
		}
	}
	
	///////////////////////////////////
	// Mittel Ebenen
	///////////////////////////////////////

	
	private AbstractGraph<Knoten, DefaultWeightedEdge> createGewichtetUnAttrGraph() {
		AbstractGraph<Knoten, DefaultWeightedEdge> tGraph;
		if(isGerichtet){
			tGraph = new DefaultDirectedWeightedGraph<Knoten, DefaultWeightedEdge>(DefaultWeightedEdge.class);
			return buildGerichtetUnAttrGewichtetGraph(tGraph);
		}else{
            boolean eurican = false;
            AbstractGraph<Knoten, DefaultWeightedEdge> tmpGraph;
            do{
                tGraph = new WeightedPseudograph<Knoten, DefaultWeightedEdge>(DefaultWeightedEdge.class);
                tmpGraph = buildUnGerichtetUnAttrGewichtetGraph(tGraph);
                eurican = EulerianCircuit.isEulerian((UndirectedGraph<Knoten, DefaultWeightedEdge>) tmpGraph);
                System.err.println("isEulerian: " + eurican);
            } while(isZusammenhängend && !eurican);
			return tmpGraph;
		}
	}

	private AbstractGraph<Knoten, DefaultWeightedEdge> createGewichtetAttrGraph(){
		AbstractGraph<Knoten, DefaultWeightedEdge> tGraph;
		if(isGerichtet){
			tGraph = new DefaultDirectedWeightedGraph<Knoten, DefaultWeightedEdge>(DefaultWeightedEdge.class);
			return buildGerichtetAttrGewichtetGraph(tGraph);
		}else{
            boolean eurican = false;
            AbstractGraph<Knoten, DefaultWeightedEdge> tmpGraph;
            do{
			    tGraph = new WeightedPseudograph<Knoten, DefaultWeightedEdge>(DefaultWeightedEdge.class);
			    tmpGraph = buildUnGerichtetAttrGewichtetGraph(tGraph);
                eurican = EulerianCircuit.isEulerian((UndirectedGraph<Knoten, DefaultWeightedEdge>) tmpGraph);
                System.err.println("isEulerian: " + eurican);
            } while (isZusammenhängend && !eurican);
            return tmpGraph;
        }
	}	

	private AbstractGraph<Knoten, DefaultEdge> createAttrUnGewichtetGraph() {
		AbstractGraph<Knoten, DefaultEdge> tgraph;
		if(isGerichtet){
			tgraph = new DirectedPseudograph<Knoten, DefaultEdge>(DefaultEdge.class);
			return buildGerichtetAttrUnGewichtet(tgraph);
		}else{
            boolean eurican = false;
            AbstractGraph<Knoten, DefaultEdge> tmpGraph;
            do{
			    tgraph = new Pseudograph<Knoten, DefaultEdge>(DefaultEdge.class);
			    tmpGraph = buildUnGerichtetAttrUnGewichtet(tgraph);
                eurican =  EulerianCircuit.isEulerian((UndirectedGraph<Knoten, DefaultEdge>) tmpGraph);
                System.err.println("isEulerian: " + eurican);
            } while(isZusammenhängend && !eurican);
		    return tmpGraph;
        }
	}

	private AbstractGraph<?, DefaultEdge> createUnAttrUnGewichtetGraph() {
		AbstractGraph<String, DefaultEdge> tGraph;
		if(isGerichtet){
			tGraph = new DirectedPseudograph<String, DefaultEdge>(DefaultEdge.class);
			return buildGerichtetUnAttrUnGewichtet(tGraph);
		}else{
			tGraph = new Pseudograph<String, DefaultEdge>(DefaultEdge.class);
			return buildUnGerichtetUnAttrUnGewichtet(tGraph);
		}	
	}

	/////////////////////////////////////////
	// Unterste Ebene
	////////////////////////////////////


	private AbstractGraph<Knoten, DefaultWeightedEdge> buildUnGerichtetAttrGewichtetGraph(AbstractGraph<Knoten, DefaultWeightedEdge> tGraph) {
		CompleteGraphGenerator<Knoten, DefaultWeightedEdge> cGG = new CompleteGraphGenerator<Knoten, DefaultWeightedEdge>(anzahlKnoten);
		return (AbstractGraph<Knoten, DefaultWeightedEdge>) buildKnotenGraph(cGG, tGraph, true);
	}


	private AbstractGraph<Knoten, DefaultWeightedEdge> buildGerichtetAttrGewichtetGraph(AbstractGraph<Knoten, DefaultWeightedEdge> tGraph) {
		CompleteGraphGenerator<Knoten, DefaultWeightedEdge> cGG = new CompleteGraphGenerator<Knoten, DefaultWeightedEdge>(anzahlKnoten);
		return (AbstractGraph<Knoten, DefaultWeightedEdge>) buildKnotenGraph(cGG, tGraph,true);
	}
	
	private AbstractGraph<Knoten, DefaultEdge> buildGerichtetAttrUnGewichtet(AbstractGraph<Knoten, DefaultEdge> tgraph) {
		CompleteGraphGenerator<Knoten, DefaultEdge> cGG = new CompleteGraphGenerator<Knoten, DefaultEdge>(anzahlKnoten);
		return (AbstractGraph<Knoten, DefaultEdge>) buildKnotenGraph(cGG, tgraph,true);
	}


	private AbstractGraph<Knoten, DefaultEdge> buildUnGerichtetAttrUnGewichtet(AbstractGraph<Knoten, DefaultEdge> tgraph) {
		CompleteGraphGenerator<Knoten, DefaultEdge> cGG = new CompleteGraphGenerator<Knoten, DefaultEdge>(anzahlKnoten);
		return (AbstractGraph<Knoten, DefaultEdge>) buildKnotenGraph(cGG, tgraph,true);
	}
	
	private AbstractGraph<String, DefaultEdge> buildUnGerichtetUnAttrUnGewichtet(AbstractGraph<String, DefaultEdge> tGraph) {
		CompleteGraphGenerator<String, DefaultEdge> cGG = new CompleteGraphGenerator<String, DefaultEdge>(anzahlKnoten);
		return (AbstractGraph<String, DefaultEdge>) buildStringGraph(cGG, tGraph);
	}

	private AbstractGraph<String, DefaultEdge> buildGerichtetUnAttrUnGewichtet(AbstractGraph<String, DefaultEdge> tGraph) {
		CompleteGraphGenerator<String, DefaultEdge> cGG = new CompleteGraphGenerator<String, DefaultEdge>(anzahlKnoten);
		return (AbstractGraph<String, DefaultEdge>) buildStringGraph(cGG, tGraph);
	}

	private AbstractGraph<Knoten, DefaultWeightedEdge> buildUnGerichtetUnAttrGewichtetGraph(AbstractGraph<Knoten, DefaultWeightedEdge> tGraph) {
		CompleteGraphGenerator<Knoten, DefaultWeightedEdge> cGG = new CompleteGraphGenerator<Knoten, DefaultWeightedEdge>(anzahlKnoten);
		return (AbstractGraph<Knoten, DefaultWeightedEdge>) buildKnotenGraph(cGG, tGraph, false);
	}
	
	private AbstractGraph<Knoten, DefaultWeightedEdge> buildGerichtetUnAttrGewichtetGraph(AbstractGraph<Knoten, DefaultWeightedEdge> tGraph) {
	    CompleteGraphGenerator<String, DefaultWeightedEdge> cGG = new CompleteGraphGenerator<String, DefaultWeightedEdge>(anzahlKnoten);
        return  (AbstractGraph<Knoten, DefaultWeightedEdge>) buildKnotenGraph(cGG, tGraph, false);
	}
	
	private AbstractGraph<String, ?> buildStringGraph(CompleteGraphGenerator generator, AbstractGraph<String, ?> aGraph){
		VertexFactory<String> vertexFactory = new VertexFactory<String>() {
			private int i = 0;
			public String createVertex() {
				return new String(""+ (i++));
			}
		};		
		generator.generateGraph(aGraph, vertexFactory, null);
		Random r = new Random();
        if(isSelfEgdes){
            Set<List<Integer>> listOfRemoveEges = new HashSet<List<Integer>>();

            while(aGraph.edgeSet().size() != userEdges){
                List<Integer> tmpList = new ArrayList<Integer>();
                Integer from = r.nextInt(anzahlKnoten);
                Integer to = r.nextInt(anzahlKnoten);

                tmpList.add(from);
                tmpList.add(to);
                if(!listOfRemoveEges.contains(tmpList) && to != from){
                    listOfRemoveEges.add(tmpList);
                    aGraph.removeEdge( ""+from, ""+to);
                }
            }
        }  else {
            int numEdges = aGraph.edgeSet().size();
            System.out.println("Eingang Edges = "+ numEdges);
            for (int i = 0; i < numEdges; i++) {
                Integer from = r.nextInt(anzahlKnoten);
                Integer to = r.nextInt(anzahlKnoten);
                aGraph.removeEdge(""+from, ""+to);
            }
        }
        lblAusgabe.setText("Vertext: " + aGraph.vertexSet().size() + " Edges: " + aGraph.edgeSet().size());
        return aGraph;
	}
	
	public AbstractGraph<Knoten, ?> buildKnotenGraph(CompleteGraphGenerator generator, AbstractGraph<Knoten, ?> aGraph, final boolean isAttr){
		setHeur = new HashSet<Integer>();
		VertexFactory<Knoten> vertexFactory = new VertexFactory<Knoten>() {
            private int i = 0;
            public Knoten createVertex() {
                if(i == 0){
                    int tmp = (i++);
                    if(isAttr) return new Knoten(""+ tmp,  tmp);
                    else return new Knoten(""+tmp);
                }else{
                    boolean tmp = true;
                    Random r = new Random();
                    int n = 0;
                    while(tmp){
                        n = (r.nextInt(anzahlKnoten * 4)+1);
                        if(!setHeur.contains(n)){
                        setHeur.add(n);
                        tmp =false;
                        }
                    }
                    if(isAttr)	return new Knoten(""+(i++), n);
                    else return new Knoten(""+(i++));
                }
            }
        };
        generator.generateGraph(aGraph, vertexFactory, null);
        Random r = new Random();

        int numEdges = aGraph.edgeSet().size();
        System.out.println("Eingang Edges = "+ numEdges );
        if(isSelfEgdes)
            numEdges = userEdges;
        else{
            numEdges = numEdges / (r.nextInt(7) +  2);
        }

        System.out.println("Eingang Edges = "+ numEdges );

        Set<List<Integer>> listOfRemoveEges = new HashSet<List<Integer>>();
            while(aGraph.edgeSet().size() != numEdges){
                List<Integer> tmpList = new ArrayList<Integer>();
                Integer from = r.nextInt(anzahlKnoten);
                Integer to = r.nextInt(anzahlKnoten);

                tmpList.add(from);
                tmpList.add(to);
                if(!listOfRemoveEges.contains(tmpList) && to != from){
                    listOfRemoveEges.add(tmpList);
                    aGraph.removeEdge(getKnoten(aGraph, ""+from), getKnoten(aGraph, ""+to));
                }
            }

        if(isZusammenhängend){
            List<Knoten> ungeradeKantenKnoten = new ArrayList<Knoten>();
            for(Knoten elem : aGraph.vertexSet()){
                if(((UndirectedGraph) aGraph).degreeOf(elem) % 2 ==1){
                    ungeradeKantenKnoten.add(elem);
                }
            }
            do{
               Knoten a = ungeradeKantenKnoten.remove(r.nextInt(ungeradeKantenKnoten.size()));
               Knoten b = ungeradeKantenKnoten.remove(r.nextInt(ungeradeKantenKnoten.size()));
               aGraph.addEdge(a,b);
            }while(!ungeradeKantenKnoten.isEmpty());
        }

        System.out.println("Anzahl Edges: " + aGraph.edgeSet().size());

        System.err.println("SetOfRemoveEgdes: " + listOfRemoveEges + " Size: " + listOfRemoveEges.size() + "Zusammenhängend: " + isZusammenhängend);
        Iterator<?> iterEdges = aGraph.edgeSet().iterator();
		while(iterEdges.hasNext()){
			Object obj = iterEdges.next();
			if(obj instanceof DefaultWeightedEdge){
				aGraph = buildHeu(aGraph, (DefaultWeightedEdge) obj, isAttr);
			}else{
				break;
			}
		}
        lblAusgabe.setText("Vertext: " + aGraph.vertexSet().size() + " Edges: " + aGraph.edgeSet().size());
		return aGraph;
	}

    private Knoten getKnoten(AbstractGraph<Knoten, ?> aGraph, String knotenName){
		Iterator<Knoten> iterVertex =  aGraph.vertexSet().iterator();
		while(iterVertex.hasNext()){
			Knoten a = iterVertex.next();
			if(a.getName().equals(knotenName)) return a;
		}
		return null;
	}
	
	
	private AbstractGraph<Knoten, ?> buildHeu(AbstractGraph<Knoten, ?> aGraph, DefaultWeightedEdge dwe, boolean isAttr){
		if(aGraph instanceof DefaultDirectedWeightedGraph){
			DefaultDirectedWeightedGraph<Knoten, DefaultWeightedEdge> tmp = (DefaultDirectedWeightedGraph)aGraph; 
			Knoten start = tmp.getEdgeSource(dwe);
			Knoten ende = tmp.getEdgeTarget(dwe);

            if(isAttr)tmp.setEdgeWeight(dwe, getKnoten(tmp, start.getName()).dstHeu(getKnoten(aGraph, ende.getName())));
			else tmp.setEdgeWeight(dwe, randomHeu());
            return tmp;
		}else if(aGraph instanceof WeightedPseudograph){
			WeightedPseudograph<Knoten, DefaultWeightedEdge> tmp = (WeightedPseudograph)aGraph; 
			Knoten start = tmp.getEdgeSource(dwe);
			Knoten ende = tmp.getEdgeTarget(dwe);
			if(isAttr)tmp.setEdgeWeight(dwe, getKnoten(tmp, start.getName()).dstHeu(getKnoten(aGraph, ende.getName())));
			else tmp.setEdgeWeight(dwe, randomHeu());
            return tmp;
		}
        lblAusgabe.setText("Vertext: " + aGraph.vertexSet().size() + " Edges: " + aGraph.edgeSet().size());
        return aGraph;
	}

    private void ausgabe(AbstractGraph abstractGraph){
        if(abstractGraph.edgeSet().size()%2 == 0)
            lblAusgabe.setText("Vertext: " + abstractGraph.vertexSet().size() + " Edges: " + abstractGraph.edgeSet().size());
        else
            lblAusgabe.setText("Vertext: " + abstractGraph.vertexSet().size() + " Edges: " + (abstractGraph.edgeSet().size()+1));

    }
	
	////////////////////////////////////////
	//
	///////////////////////
    private Set<Integer> heuRandomSet = new HashSet<Integer>();

    private int randomHeu(){
        boolean  tmp = true;
        int result =0;
        while(tmp){
              int zahl = (int)(Math.random()*1000);
              if(!heuRandomSet.contains(zahl)){
                  heuRandomSet.add(zahl);
                  result = zahl;
                  tmp = false;
              }
        }
        return result;
    }

	void cancelAction(ActionEvent e){
		this.setVisible(false);
	}
	
	private void out(String str){
		System.out.println(str);
	}
	
	private void switchGraph(){
		isAttr = checkAttr.isSelected();
		isGerichtet = checkGerichtet.isSelected();
		isGewichtet = checkGewichtet.isSelected();
        isZusammenhängend = checkZusammen.isSelected();
        isSelfEgdes = checkManualEdges.isSelected();
	}


    private boolean removeVertex(AbstractGraph<Knoten, ?> abstractGraph){
        boolean tmp = false;
        for(Knoten elem : abstractGraph.vertexSet()){
            tmp = abstractGraph.removeVertex(elem);

        }
        return tmp;
    }
	
	private JCheckBox checkGewichtet = new JCheckBox("Gewichtet?");
	private JCheckBox checkAttr = new JCheckBox("Attributiert?");
	private JCheckBox checkGerichtet = new JCheckBox("Gerichtet?");
	private JCheckBox checkZusammen = new JCheckBox("Euer?");
    private JCheckBox checkManualEdges = new JCheckBox("Edges selbstbestimmen", true);

    private int userEdges;
    private int maxEdges;

	private JLabel lblAnzahlKnoten = new JLabel("Anzahl an Vertex: ");
    private JLabel lblAnzahlKanten = new JLabel("Anzahl an Edges: ");
	private JLabel lblMaxAnzahlKanten = new JLabel("Maximale Anzahl Edges: ");
    private JLabel lblAnzeigeMaxKanten = new JLabel();

    private JLabel lblAusgabe = new JLabel();

	private JTextField txtAnzahlKnoten = new JTextField();
    private JTextField txtAnzahlKanten = new JTextField();

	private JButton btnCreate = new JButton("Graph erzeugen");
	private JButton btnCancel = new JButton("Cancel");
	
	private boolean isGewichtet =false;
	private boolean isAttr = false;
	private boolean isGerichtet = false;
    private boolean isZusammenhängend = false;
    private boolean isSelfEgdes = true;

    private Set<Integer>  setHeur;


}
